// -*- coding: utf-8 -*-
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "filecomparator.h"
#include "syncdialog.h"
#include <QSettings>
#include <QCoreApplication>
#include <QScrollBar>
#include <QProcess>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QCheckBox>
#include <QLineEdit>
#include <QPushButton>
#include <QLabel>
#include <QMenu>
#include <QAction>
#include <QFileInfo>
#include <QFileDialog>
#include <QDir>
#include <QTreeWidgetItem>
#include <QDebug>
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , m_fileComparator(new FileComparator(this))
    , m_useExternalDiffTool(false) // 默认不使用外部比较器
{
    ui->setupUi(this);
    setWindowTitle("Java/Kt Refactor Diff Tool");
    
    // 设置树形视图属性
    ui->treeWidget->setHeaderLabel("左侧目录");
    ui->treeWidget_2->setHeaderLabel("右侧目录");
    
    // 清空输出区域
    ui->resultTextEdit->clear();
    
    // 创建设置菜单
    QMenu *settingsMenu = menuBar()->addMenu("设置");
    QAction *settingsAction = new QAction("比较器设置", this);
    connect(settingsAction, &QAction::triggered, this, &MainWindow::on_settingsAction_triggered);
    settingsMenu->addAction(settingsAction);
    
    // 连接左右目录树的垂直滚动条，实现同步滚动
    connect(ui->treeWidget->verticalScrollBar(), &QScrollBar::valueChanged, this, [=](int value) {
        // 使用setValue而不是直接设置值，确保视图正确刷新
        if (ui->treeWidget_2->verticalScrollBar()->value() != value) {
            ui->treeWidget_2->verticalScrollBar()->blockSignals(true);
            ui->treeWidget_2->verticalScrollBar()->setValue(value);
            // 强制视图更新
            ui->treeWidget_2->viewport()->update();
            ui->treeWidget_2->verticalScrollBar()->blockSignals(false);
        }
    });
    
    connect(ui->treeWidget_2->verticalScrollBar(), &QScrollBar::valueChanged, this, [=](int value) {
        // 使用setValue而不是直接设置值，确保视图正确刷新
        if (ui->treeWidget->verticalScrollBar()->value() != value) {
            ui->treeWidget->verticalScrollBar()->blockSignals(true);
            ui->treeWidget->verticalScrollBar()->setValue(value);
            // 强制视图更新
            ui->treeWidget->viewport()->update();
            ui->treeWidget->verticalScrollBar()->blockSignals(false);
        }
    });
    
    // 加载上次的目录设置
    loadSettings();
}

MainWindow::~MainWindow()
{
    // 保存当前设置
    saveSettings();
    delete ui;
}

void MainWindow::on_selectLeftDirButton_clicked()
{
    QString dirPath = QFileDialog::getExistingDirectory(this, "选择左侧目录", 
                                                       !m_leftDirPath.isEmpty() ? m_leftDirPath : "");
    if (!dirPath.isEmpty()) {
        m_leftDirPath = dirPath;
        ui->leftDirLineEdit->setText(dirPath);
        populateDirectoryTree(ui->treeWidget, dirPath);
        
        // 保存设置
        saveSettings();
    }
}

void MainWindow::on_selectRightDirButton_clicked()
{
    QString dirPath = QFileDialog::getExistingDirectory(this, "选择右侧目录", 
                                                       !m_rightDirPath.isEmpty() ? m_rightDirPath : "");
    if (!dirPath.isEmpty()) {
        m_rightDirPath = dirPath;
        ui->rightDirLineEdit->setText(dirPath);
        populateDirectoryTree(ui->treeWidget_2, dirPath);
        
        // 保存设置
        saveSettings();
    }
}

void MainWindow::on_compareButton_clicked()
{
    if (m_leftDirPath.isEmpty() || m_rightDirPath.isEmpty()) {
        QMessageBox::warning(this, "警告", "请先选择左右两个目录");
        return;
    }
    
    compareDirectories();
}

void MainWindow::populateDirectoryTree(QTreeWidget *treeWidget, const QString &dirPath)
{
    treeWidget->clear();
    
    QDirIterator it(dirPath, QDir::AllEntries | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
    QMap<QString, QTreeWidgetItem*> pathItemMap;
    
    // 添加根目录
    QTreeWidgetItem *rootItem = new QTreeWidgetItem(treeWidget);
    rootItem->setText(0, QFileInfo(dirPath).fileName());
    rootItem->setData(0, Qt::UserRole, dirPath);
    pathItemMap[dirPath] = rootItem;
    
    while (it.hasNext()) {
        it.next();
        QString filePath = it.filePath();
        QString dir = it.fileInfo().dir().absolutePath();
        
        QTreeWidgetItem *parentItem = pathItemMap.value(dir);
        if (!parentItem) {
            // 如果父目录项不存在，递归创建
            QStringList parts = dir.split("/", Qt::SkipEmptyParts);
            QString currentPath = "/";
            for (const QString &part : parts) {
                currentPath += part + "/";
                if (!pathItemMap.contains(currentPath)) {
                    QTreeWidgetItem *newParent = new QTreeWidgetItem(pathItemMap.value(currentPath.left(currentPath.length() - part.length() - 1)));
                    newParent->setText(0, part);
                    newParent->setData(0, Qt::UserRole, currentPath);
                    pathItemMap[currentPath] = newParent;
                }
                parentItem = pathItemMap.value(currentPath);
            }
        }
        
        QTreeWidgetItem *item = new QTreeWidgetItem(parentItem);
        item->setText(0, it.fileName());
        item->setData(0, Qt::UserRole, filePath);
        
        if (it.fileInfo().isDir()) {
            pathItemMap[filePath] = item;
        }
    }
    
    treeWidget->expandAll();
}

QString MainWindow::extractTopLevelPackage(const QString &dirPath)
{
    // 收集目录中的所有Java和Kotlin文件
    QStringList javaKtFiles;
    QDirIterator it(dirPath, QStringList() << "*.java" << "*.kt", QDir::Files, QDirIterator::Subdirectories);
    
    while (it.hasNext()) {
        javaKtFiles << it.next();
    }
    
    // 对于每个文件，提取包名并找出最上层的包名
    QString topLevelPackage;
    foreach (const QString &filePath, javaKtFiles) {
        QFile file(filePath);
        if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            QTextStream stream(&file);
            QString content = stream.readAll();
            file.close();
            
            // 提取包名
            QRegularExpression packageRegex("^\\s*package\\s+([\\w.]+)\\s*;?\\s*$", QRegularExpression::MultilineOption);
            QRegularExpressionMatch match = packageRegex.match(content);
            if (match.hasMatch()) {
                QString packageName = match.captured(1);
                // 如果还没有找到包名，或者当前包名是更上层的（更少的点号）
                if (topLevelPackage.isEmpty() || 
                    packageName.split(".").size() < topLevelPackage.split(".").size()) {
                    topLevelPackage = packageName;
                }
            }
        }
    }
    
    return topLevelPackage;
}

void MainWindow::compareDirectories()
{
    ui->resultTextEdit->clear();
    ui->resultTextEdit->append("开始比较目录...");
    
    // 清除之前的红色标记
    QTreeWidgetItemIterator resetItLeft(ui->treeWidget);
    while (*resetItLeft) {
        (*resetItLeft)->setForeground(0, Qt::black); // 恢复默认颜色
        ++resetItLeft;
    }
    
    QTreeWidgetItemIterator resetItRight(ui->treeWidget_2);
    while (*resetItRight) {
        (*resetItRight)->setForeground(0, Qt::black); // 恢复默认颜色
        ++resetItRight;
    }
    
    // 从左右目录分别提取最上层包名
    QString leftTopPackage = extractTopLevelPackage(m_leftDirPath);
    QString rightTopPackage = extractTopLevelPackage(m_rightDirPath);
    
    // 设置左侧最上层包名到FileComparator
    if (!leftTopPackage.isEmpty()) {
        m_fileComparator->setLeftTopLevelPackage(leftTopPackage);
        ui->resultTextEdit->append(QString("已设置左侧最上层包名：%1").arg(leftTopPackage));
    }
    
    // 设置右侧最上层包名到FileComparator
    if (!rightTopPackage.isEmpty()) {
        m_fileComparator->setRightTopLevelPackage(rightTopPackage);
        ui->resultTextEdit->append(QString("已设置右侧最上层包名：%1").arg(rightTopPackage));
    }
    
    // 收集左右两侧的所有文件
    QStringList leftFiles, rightFiles;
    QDirIterator leftIt(m_leftDirPath, QDir::Files, QDirIterator::Subdirectories);
    while (leftIt.hasNext()) {
        leftFiles << leftIt.next();
    }
    
    QDirIterator rightIt(m_rightDirPath, QDir::Files, QDirIterator::Subdirectories);
    while (rightIt.hasNext()) {
        rightFiles << rightIt.next();
    }
    
    ui->resultTextEdit->append(QString("左侧找到 %1 个文件，右侧找到 %2 个文件").arg(leftFiles.size()).arg(rightFiles.size()));
    
    // 比较同名文件
    int differentFilesCount = 0;
    int totalCompared = 0;
    
    for (const QString &leftFile : leftFiles) {
        QString fileName = QFileInfo(leftFile).fileName();
        
        // 查找右侧是否有同名文件
        for (const QString &rightFile : rightFiles) {
            if (QFileInfo(rightFile).fileName() == fileName) {
                totalCompared++;
                
                // 更新进度
                if (totalCompared % 10 == 0) {
                    ui->resultTextEdit->append(QString("已比较 %1 个文件...").arg(totalCompared));
                }
                
                // 比较文件
                bool isDifferent = m_fileComparator->compareFiles(leftFile, rightFile);
                if (isDifferent) {
                    differentFilesCount++;
                    
                    // 标记不同的文件为红色
                    QTreeWidgetItemIterator it(ui->treeWidget);
                    while (*it) {
                        if ((*it)->data(0, Qt::UserRole).toString() == leftFile) {
                            (*it)->setForeground(0, Qt::red);
                            break;
                        }
                        ++it;
                    }
                    
                    QTreeWidgetItemIterator it2(ui->treeWidget_2);
                    while (*it2) {
                        if ((*it2)->data(0, Qt::UserRole).toString() == rightFile) {
                            (*it2)->setForeground(0, Qt::red);
                            break;
                        }
                        ++it2;
                    }
                }
                
                break;
            }
        }
    }
    
    ui->resultTextEdit->append("比较完成！");
    ui->resultTextEdit->append(QString("共比较 %1 对同名文件，其中 %2 对文件不同").arg(totalCompared).arg(differentFilesCount));
}

void MainWindow::on_treeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)
{
    QString leftFilePath = item->data(0, Qt::UserRole).toString();
    if (QFileInfo(leftFilePath).isFile()) {
        // 查找右侧同名文件
        QString fileName = QFileInfo(leftFilePath).fileName();
        QString rightFilePath;
        
        QTreeWidgetItemIterator it(ui->treeWidget_2);
        while (*it) {
            if ((*it)->text(0) == fileName && QFileInfo((*it)->data(0, Qt::UserRole).toString()).isFile()) {
                rightFilePath = (*it)->data(0, Qt::UserRole).toString();
                break;
            }
            ++it;
        }
        
        if (!rightFilePath.isEmpty()) {
            showFileContent(leftFilePath, rightFilePath);
        } else {
            QMessageBox::information(this, "提示", "右侧没有找到同名文件");
        }
    }
}

void MainWindow::on_treeWidget_2_itemDoubleClicked(QTreeWidgetItem *item, int column)
{
    QString rightFilePath = item->data(0, Qt::UserRole).toString();
    if (QFileInfo(rightFilePath).isFile()) {
        // 查找左侧同名文件
        QString fileName = QFileInfo(rightFilePath).fileName();
        QString leftFilePath;
        
        QTreeWidgetItemIterator it(ui->treeWidget);
        while (*it) {
            if ((*it)->text(0) == fileName && QFileInfo((*it)->data(0, Qt::UserRole).toString()).isFile()) {
                leftFilePath = (*it)->data(0, Qt::UserRole).toString();
                break;
            }
            ++it;
        }
        
        if (!leftFilePath.isEmpty()) {
            showFileContent(leftFilePath, rightFilePath);
        } else {
            QMessageBox::information(this, "提示", "左侧没有找到同名文件");
        }
    }
}
void MainWindow::launchExternalDiffTool(const QString &leftFilePath, const QString &rightFilePath)
{
    if (m_useExternalDiffTool && !m_externalDiffTool.isEmpty()) {
        QString command = m_externalDiffTool;
        // 替换占位符或直接添加文件路径
        // 假设外部工具的命令行格式为: tool.exe file1 file2
        command += " \"" + leftFilePath + "\" \"" + rightFilePath + "\"";
        
        QProcess process;
        bool success = process.startDetached(command);
        
        if (!success) {
            QMessageBox::warning(this, "启动失败", QString("无法启动外部比较器: %1").arg(m_externalDiffTool));
        }
    }
}

void MainWindow::on_settingsAction_triggered()
{
    QDialog *settingsDialog = new QDialog(this);
    settingsDialog->setWindowTitle("比较器设置");
    settingsDialog->setFixedSize(400, 200);
    
    QVBoxLayout *mainLayout = new QVBoxLayout(settingsDialog);
    
    // 使用外部比较器复选框
    QCheckBox *useExternalDiffCheckBox = new QCheckBox("使用外部文件比较器");
    useExternalDiffCheckBox->setChecked(m_useExternalDiffTool);
    
    // 外部比较器路径输入
    QHBoxLayout *pathLayout = new QHBoxLayout();
    QLabel *pathLabel = new QLabel("比较器路径:");
    QLineEdit *pathLineEdit = new QLineEdit(m_externalDiffTool);
    QPushButton *browseButton = new QPushButton("浏览");
    
    pathLayout->addWidget(pathLabel);
    pathLayout->addWidget(pathLineEdit);
    pathLayout->addWidget(browseButton);
    
    // 连接浏览按钮
    connect(browseButton, &QPushButton::clicked, this, [=]() {
        QString filePath = QFileDialog::getOpenFileName(this, "选择外部比较器", 
                                                       QFileInfo(m_externalDiffTool).absolutePath(), 
                                                       "可执行文件 (*.exe);;所有文件 (*.*)");
        if (!filePath.isEmpty()) {
            pathLineEdit->setText(filePath);
        }
    });
    
    // 根据复选框状态启用/禁用路径输入
    pathLineEdit->setEnabled(m_useExternalDiffTool);
    browseButton->setEnabled(m_useExternalDiffTool);
    
    connect(useExternalDiffCheckBox, &QCheckBox::toggled, this, [=](bool checked) {
        pathLineEdit->setEnabled(checked);
        browseButton->setEnabled(checked);
    });
    
    // 提示标签
    QLabel *hintLabel = new QLabel("提示: 外部比较器将使用 '程序路径 文件1 文件2' 的命令行格式启动");
    hintLabel->setWordWrap(true);
    hintLabel->setStyleSheet("color: #666;");
    
    // 按钮布局
    QHBoxLayout *buttonLayout = new QHBoxLayout();
    QPushButton *okButton = new QPushButton("确定");
    QPushButton *cancelButton = new QPushButton("取消");
    
    buttonLayout->addStretch();
    buttonLayout->addWidget(okButton);
    buttonLayout->addWidget(cancelButton);
    
    // 添加所有组件到主布局
    mainLayout->addWidget(useExternalDiffCheckBox);
    mainLayout->addLayout(pathLayout);
    mainLayout->addWidget(hintLabel);
    mainLayout->addLayout(buttonLayout);
    
    // 连接按钮
    connect(okButton, &QPushButton::clicked, this, [=]() {
        m_useExternalDiffTool = useExternalDiffCheckBox->isChecked();
        m_externalDiffTool = pathLineEdit->text();
        saveSettings(); // 保存设置
        settingsDialog->accept();
    });
    
    connect(cancelButton, &QPushButton::clicked, settingsDialog, &QDialog::reject);
    
    settingsDialog->exec();
    delete settingsDialog;
}

void MainWindow::loadSettings()
{
    // 获取可执行文件所在目录
    QString appDir = QCoreApplication::applicationDirPath();
    QString configPath = appDir + "/config.ini";
    
    // 使用IniFormat格式，并指定配置文件路径
    QSettings settings(configPath, QSettings::IniFormat);
    
    // 加载左侧目录路径
    m_leftDirPath = settings.value("Paths/LeftDirPath").toString();
    if (!m_leftDirPath.isEmpty()) {
        ui->leftDirLineEdit->setText(m_leftDirPath);
        QDir dir(m_leftDirPath);
        if (dir.exists()) {
            populateDirectoryTree(ui->treeWidget, m_leftDirPath);
        }
    }
    
    // 加载右侧目录路径
    m_rightDirPath = settings.value("Paths/RightDirPath").toString();
    if (!m_rightDirPath.isEmpty()) {
        ui->rightDirLineEdit->setText(m_rightDirPath);
        QDir dir(m_rightDirPath);
        if (dir.exists()) {
            populateDirectoryTree(ui->treeWidget_2, m_rightDirPath);
        }
    }
    
    // 加载外部比较器设置
    m_useExternalDiffTool = settings.value("DiffTool/UseExternal", false).toBool();
    m_externalDiffTool = settings.value("DiffTool/Path", "").toString();
}

void MainWindow::saveSettings()
{
    // 获取可执行文件所在目录
    QString appDir = QCoreApplication::applicationDirPath();
    QString configPath = appDir + "/config.ini";
    
    // 使用IniFormat格式，并指定配置文件路径
    QSettings settings(configPath, QSettings::IniFormat);
    
    // 使用分组以便更好地组织配置项
    settings.beginGroup("Paths");
    settings.setValue("LeftDirPath", m_leftDirPath);
    settings.setValue("RightDirPath", m_rightDirPath);
    settings.endGroup();
    
    // 保存外部比较器设置
    settings.beginGroup("DiffTool");
    settings.setValue("UseExternal", m_useExternalDiffTool);
    settings.setValue("Path", m_externalDiffTool);
    settings.endGroup();
}

void MainWindow::showFileContent(const QString &leftFilePath, const QString &rightFilePath)
{
    if (m_useExternalDiffTool && !m_externalDiffTool.isEmpty()) {
        // 使用外部比较器
        launchExternalDiffTool(leftFilePath, rightFilePath);
    } else {
        // 使用内部比较器
        SyncDialog *dialog = new SyncDialog(leftFilePath, rightFilePath, this);
        dialog->show();
    }
}